package com.wiken.storeservice.rocketmq.consumer;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.wiken.servicecommon.common.Code;
import com.wiken.servicecommon.common.exception.DefaultException;
import com.wiken.storeservice.entity.StoreActivity;
import com.wiken.storeservice.entity.UserStoreActivity;
import com.wiken.storeservice.service.impl.StoreActivityServiceImpl;
import com.wiken.storeservice.service.impl.UserStoreActivityServiceImpl;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Component
@RocketMQMessageListener(topic="activity", consumerGroup = "activity_group2")
@Transactional
public class AddUserStoreActivityConsumer2 implements RocketMQListener<String> {

    @Value("${properties.workId}")
    private long workId;

    @Value("${properties.datacenterId}")
    private long datacenterId;

    @Autowired
    private StoreActivityServiceImpl storeActivityService;

    @Autowired
    private UserStoreActivityServiceImpl userStoreActivityService;

    @Autowired
    private RedissonClient redisson;
    
    private final String ACTIVITY_LOCK = "activity:lock";

    @Override
    public void onMessage(String json) {
        UserStoreActivity userStoreActivity = JSON.parseObject(json, UserStoreActivity.class);
        Snowflake snowflake = IdUtil.getSnowflake(workId, datacenterId);
        //如果优惠劵未领取，查看该优惠劵是否有限，如果有限就删减库存

        //查看优惠劵是否有限
        StoreActivity storeActivity = storeActivityService.getById(userStoreActivity.getActivityId());
        if(storeActivity.getLimited() == 1){

            //=================================删减库存

            RLock lock = redisson.getLock(ACTIVITY_LOCK);
           lock.tryLock();

            //判断库存是否大于0，如果小于0，提示库存不足
            if(storeActivity.getNumber() <= 0) throw new DefaultException(Code.ERROR_STORE_ACTIVITY_STORE_NUMBER_ZERO, "库存不足");
            //此处可能会造成因为高并发而导致的库存超卖的问题，已经尝试使用乐观锁CAS解决
            boolean success = storeActivityService.discountStoreNumberById(storeActivity.getId());

            lock.unlock();

            if(!success) throw new DefaultException(Code.ERROR_STORE_ACTIVITY_STORE_NUMBER_DELETE, "删减库存失败");
        }

        long id = snowflake.nextId();

        userStoreActivity.setId(id+"");
        boolean success = userStoreActivityService.save(userStoreActivity);
    }
}
